package com.have.blog.admin.redis.impl;


import com.have.blog.security.bo.OnlineAdmin;
import com.have.blog.admin.constant.AdminBlogConstant;
import com.have.blog.admin.constant.AdminRedisConstant;
import com.have.blog.admin.redis.AdminLoginCacheService;
import com.have.blog.base.constant.BaseConstant;
import com.have.blog.config.hloder.RequestHolder;
import com.have.blog.config.service.RedisService;
import com.have.blog.model.models.Admin;
import com.have.blog.model.models.ResourceMenu;
import com.have.blog.utils.DateUtils;
import com.have.blog.utils.IpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class AdminLoginCacheServiceImpl implements AdminLoginCacheService {
    @Autowired
    private RedisService redisService;
    @Value("${redis.admin.database}")
    private String REDIS_KEY_DATABASE;

    @Override
    public String getLoginErrorCount(String ip) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.LOGIN_LIMIT + AdminRedisConstant.SEGMENTATION + ip;
        return (String)redisService.get(key);
    }

    @Override
    public void setLoginErrorCount(String ip, String count, Integer expiredTime, TimeUnit timeUnit) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.LOGIN_LIMIT + AdminRedisConstant.SEGMENTATION + ip;
        redisService.set(key, count, expiredTime, timeUnit);
    }

    @Override
    public void delLoginErrorCount(String ip) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.LOGIN_LIMIT + AdminRedisConstant.SEGMENTATION + ip;
        redisService.del(key);
    }


    @Override
    public void addOnlineAdmin(Admin admin, String token, String tokenUid, String roleName, long expiredTime, TimeUnit timeUnit) {
        HttpServletRequest request = RequestHolder.getRequest();
        String ip = IpUtils.getIpAddr(request);
        OnlineAdmin onlineAdmin = new OnlineAdmin();
        onlineAdmin.setAdminUid(admin.getUid());
        onlineAdmin.setTokenUId(tokenUid);
        onlineAdmin.setRoleName(roleName);
        onlineAdmin.setUserName(admin.getUsername());

        String address = (String)redisService.get(AdminRedisConstant.IP_SOURCE + AdminRedisConstant.SEGMENTATION + ip);
        if (StringUtils.isEmpty(address)) {
            address = IpUtils.getAddresses(AdminBlogConstant.IP + AdminBlogConstant.EQUAL_TO + ip, AdminBlogConstant.UTF_8);
            if (!StringUtils.isEmpty(address)) {
                onlineAdmin.setLoginLocation(address);
                redisService.set(AdminRedisConstant.IP_SOURCE + AdminRedisConstant.SEGMENTATION + ip, address, 24, TimeUnit.HOURS);
            }
        } else {
            onlineAdmin.setLoginLocation(address);
        }


        // 将登录用户信息储存到redis缓存中
        String adminKey = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.LOGIN_KEY_ADMIN + BaseConstant.SYMBOL_COLON
                + token;
        redisService.set(adminKey, onlineAdmin, expiredTime, timeUnit);

        // 在缓存中记录token和UUID之间的转换
        String tokenKey = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.LOGIN_UUID_KEY + BaseConstant.SYMBOL_COLON
                + tokenUid;
        redisService.set(tokenKey, token, expiredTime, timeUnit);
    }

    @Override
    public String getToken(String tokenUid) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.LOGIN_UUID_KEY + BaseConstant.SYMBOL_COLON
                + tokenUid;
        return (String) redisService.get(key);
    }

    @Override
    public OnlineAdmin getOnlineAdmin(String token) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.LOGIN_KEY_ADMIN + BaseConstant.SYMBOL_COLON
                + token;
        return (OnlineAdmin) redisService.get(key);
    }

    @Override
    public List<OnlineAdmin> getAllOnlineAdmin() {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.LOGIN_KEY_ADMIN + BaseConstant.SYMBOL_COLON
                + BaseConstant.SYMBOL_STAR;
        Object objects = redisService.multiGet(key);
        return (List<OnlineAdmin>) objects;
    }

    @Override
    public void deleteOnlineAdmin(String token) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.LOGIN_KEY_ADMIN + BaseConstant.SYMBOL_COLON
                + token;
        redisService.del(key);
    }

    @Override
    public void deleteToken(String tokenUid) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION  +
                AdminRedisConstant.LOGIN_UUID_KEY + BaseConstant.SYMBOL_COLON
                + tokenUid;
        redisService.del(key);
    }

    @Override
    @Deprecated
    public void addResourceList(Integer adminUid, List<ResourceMenu> resourceList, Long expiredSeconds, TimeUnit timeUnit) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION +
                AdminRedisConstant.ADMIN_RESOURCE_KEY_RESOURCE_LIST +
                BaseConstant.SYMBOL_COLON + adminUid;
        redisService.set(key, resourceList, expiredSeconds, timeUnit);
    }

    @Override
    @Deprecated
    public List<ResourceMenu> getResourceList(Integer adminUid) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.ADMIN_RESOURCE_KEY_RESOURCE_LIST + BaseConstant.SYMBOL_COLON
                + adminUid;
        return (List<ResourceMenu>) redisService.get(key);
    }

    @Override
    @Deprecated
    public void deleteResourceList(Integer adminUid) {
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.ADMIN_RESOURCE_KEY_RESOURCE_LIST + AdminRedisConstant.SEGMENTATION
                + adminUid;
        redisService.del(key);
    }

    @Override
    @Deprecated
    public void deleteAllResourceList(){
        String key = REDIS_KEY_DATABASE + AdminRedisConstant.SEGMENTATION
                + AdminRedisConstant.ADMIN_RESOURCE_KEY_RESOURCE_LIST + AdminRedisConstant.SEGMENTATION
                + BaseConstant.SYMBOL_STAR;
        redisService.delAll(key);
    }
}
